﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;

namespace PlayDeezGames.Common
{
    public static class EntityFactories
    {
        #region Registry
        private static Dictionary<string, IEntityFactory> factories = new Dictionary<string, IEntityFactory>();

        public static void RegisterFactory(string theFactoryName, IEntityFactory theFactory)
        {
            factories[theFactoryName] = theFactory;
        }
        public static void UnregisterFactory(string theFactoryName)
        {
            factories.Remove(theFactoryName);
        }
        #endregion

        public static T Load<T>(IEntity theParent, XElement theXElement)
        {
            return (T)Load(theParent, theXElement);
        }
        public static IEntity Load(IEntity theParent,XElement theXElement)
        {
            if (theXElement.Attribute(Names.CommonXNames.FromResource) == null)
            {
                XAttribute attribute = theXElement.Attribute(Names.CommonXNames.Factory);
                if (attribute != null)
                {
                    return Load(attribute.Value, theParent, theXElement);
                }
                else
                {
                    return null;
                }
            }
            else
            {
                XAttribute attribute = theXElement.Attribute(Names.CommonXNames.FromResource);
                XDocument document = XDocument.Load(attribute.Value);
                return Load(theParent, document.Root);
            }
        }

        private static IEntity Load(string theFactoryName, IEntity theParent, XElement theXElement)
        {
            if (factories.ContainsKey(theFactoryName))
            {
                return factories[theFactoryName].LoadFromXElement(theParent, theXElement);
            }
            throw new IndexOutOfRangeException();
        }

        #region Create
        public static IEntity Create(IEntity theParent, string theFactoryName)
        {
            if (factories.ContainsKey(theFactoryName))
            {
                return factories[theFactoryName].Create(theParent);
            }
            throw new IndexOutOfRangeException();
        }
        public static T Create<T>(IEntity theParent, string theFactoryName)
        {
            return (T)Create(theParent, theFactoryName);
        }
        #endregion
    }
}
